package helper.com.listener;

import com.rabbitmq.client.Channel;
import helper.com.exception.CustomException;
import helper.com.utils.TimeUtil;
import helper.com.udo.RabbitmqUdo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;


import java.io.*;
import java.lang.reflect.Method;

import static helper.com.constants.RabbitmqConstants.MANAGER_QUEUE;


/**
 * @author 大忽悠
 * @create 2022/5/22 21:10
 */
@Slf4j
@Component
public class RabbitmqListener implements ApplicationContextAware {
    private ApplicationContext app;

    /**
     * 处理manager类的异步事件
     */
    @RabbitListener(queues = MANAGER_QUEUE)
    public void handleAsyncEvent(Message message, Channel channel) throws Exception {
        RabbitmqUdo rabbitmqUDO = (RabbitmqUdo)streamToObj(message.getBody());
        //准备参数
        Class<?> serviceClass = rabbitmqUDO.getServiceClass();
        Object obj = rabbitmqUDO.getObj();
        Class<?> methodClass = rabbitmqUDO.getMethodClass();
        String methodName = rabbitmqUDO.getMethodName();
        Method method = methodClass.getMethod(methodName, rabbitmqUDO.getMethodParamClass());
        //拿到容器中真正的service实体
        Object service = app.getBean(serviceClass);
        //执行方法
        method.invoke(service,obj);
        log.info("当前时间：{},关联的服务层为: {},方法名: {}, 方法实际参数: {}",
                TimeUtil.getCurTime(),serviceClass,methodName,obj);
    }


    private Object streamToObj(byte[] bytes){
        try {
            ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(bytes));
            return objectInputStream.readObject();
        } catch (IOException | ClassNotFoundException e) {
            log.error("发生错误: ",e);
            throw new CustomException(e.getMessage());
        }
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.app= applicationContext;
    }


}
